package com.jinzhi.eventresource.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.jinzhi.api.util.JWTUtil;
import com.jinzhi.common.utils.ShiroUtils;
import com.jinzhi.common.utils.StringUtil;
import com.jinzhi.eventresource.dao.EventresourceAllocationDao;
import com.jinzhi.eventresource.dao.EventresourceAllocationsDao;
import com.jinzhi.eventresource.dao.JzPermission;
import com.jinzhi.eventresource.dao.JzPermissionMapper;
import com.jinzhi.eventresource.main.EventresourceAllocationDO;
import com.jinzhi.eventresource.main.EventresourceAllocationsDO;
import com.jinzhi.eventresource.main.EventresourceModuleDO;
import com.jinzhi.eventresource.service.EventresourceAllocationsService;
import com.jinzhi.eventresource.service.EventresourceModuleService;
import com.jinzhi.eventresource.service.IJzPermissionService;
import com.jinzhi.eventresource.vo.PermissionResourceListVO;
import com.jinzhi.eventresource.vo.PermissionSaveVO;
import com.jinzhi.sys.dao.UserDao;
import com.jinzhi.sys.domain.UserDO;
import org.apache.catalina.security.SecurityUtil;
import org.apache.tomcat.jni.Lock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源库前台权限表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-09-29
 */
@Service
public class JzPermissionServiceImpl extends ServiceImpl<JzPermissionMapper, JzPermission> implements IJzPermissionService {

    @Autowired
    private JzPermissionMapper permissionMapper;
    @Autowired
    private EventresourceAllocationsDao allocationsMapper;
    @Autowired
    private EventresourceAllocationDao allocationMapper;
    @Autowired
    private JzPermissionMapper jzPermissionMapper;
    @Autowired
    private EventresourceModuleService eventresourceModuleService;
    @Autowired
    private UserDao userDao;


    @Override
    public Map<String, List<JzPermission>> list(String userId) {
        List<JzPermission> jzPermissions = jzPermissionMapper.selectList(new EntityWrapper<JzPermission>()
                .eq("user_id", userId));
        Map<String, List<JzPermission>> map = jzPermissions.stream().map(jzPermission -> {
            EventresourceAllocationDO eventresourceAllocationDO = allocationMapper.selectById(jzPermission.getAllocationId());
            EventresourceModuleDO eventresourceModuleDO = eventresourceModuleService.selectById(eventresourceAllocationDO.getJzEveMoId());
            jzPermission.setEveMoName(eventresourceModuleDO.getName());
            if (Objects.equals(eventresourceModuleDO.getName(), "1+X证书资源")) {
                jzPermission.setEveMoName("证书资源");
            }
            return jzPermission;
        }).collect(Collectors.groupingBy(JzPermission::getEveMoName));
        return map;
    }

    /**
     * 三级list 资源类型 资源菜单 菜单中组别
     *
     * @return
     */
    @Override
    public Map<String, List<PermissionResourceListVO>> resourceList() {
        Wrapper<EventresourceAllocationsDO> query = new EntityWrapper<EventresourceAllocationsDO>()
                // 目录无组别
                .eq("node_type", 0)
                .orderBy("create_time", true);
        List<EventresourceAllocationsDO> eventresourceAllocationsDOList = allocationsMapper.selectList(query);

        Map<Long, List<EventresourceAllocationsDO>> moduleTypeMap = eventresourceAllocationsDOList.stream()
                .collect(Collectors.groupingBy(EventresourceAllocationsDO::getAllocationId));

        // 类型 type groupType
        List<PermissionResourceListVO> permissionResourceListVOList = moduleTypeMap.entrySet().stream().map(entry -> {
            long allocationId = entry.getKey().longValue();

            EventresourceAllocationDO eventresourceAllocationDO = allocationMapper.selectById(allocationId);
            EventresourceModuleDO eventresourceModuleDO = eventresourceModuleService.selectById(eventresourceAllocationDO.getJzEveMoId());
            if (Objects.equals(eventresourceModuleDO.getName(), "1+X证书资源")) {
                eventresourceModuleDO.setName("证书资源");
            }

            Map<Integer, List<EventresourceAllocationsDO>> typeMap = entry.getValue().stream()
                    .collect(Collectors.groupingBy(EventresourceAllocationsDO::getType));
            List<PermissionResourceListVO> typeList = getTypeList(allocationId, typeMap, eventresourceModuleDO);

            PermissionResourceListVO permissionResourceListVO = new PermissionResourceListVO();
            permissionResourceListVO.setId(String.valueOf(allocationId));
            permissionResourceListVO.setEveMoName(eventresourceModuleDO.getName());
            permissionResourceListVO.setName(eventresourceAllocationDO.getEventName());
            permissionResourceListVO.setPermissionList(typeList);
            return permissionResourceListVO;
        }).collect(Collectors.toList());

        Map<String, List<PermissionResourceListVO>> collect = permissionResourceListVOList.stream()
                .collect(Collectors.groupingBy(PermissionResourceListVO::getEveMoName));

        return collect;
    }

    private void judge(long allocationId, Map.Entry<Integer, List<EventresourceAllocationsDO>> e2,
                       Map.Entry<Integer, List<EventresourceAllocationsDO>> e3, PermissionResourceListVO p3) {
        Long userId = ShiroUtils.getUserId();
        UserDO userDO = userDao.selectById(userId);
        if (userDO.getType() == 0) {
            userId = permissionMapper.getTeacherById(userId);
        }

        JzPermission jzPermission = new JzPermission();
        jzPermission.setUserId(userId.toString());
        jzPermission.setAllocationId(allocationId);
        jzPermission.setType(e2.getKey().intValue());
        JzPermission permission = jzPermissionMapper.selectOne(jzPermission);
        if (Objects.nonNull(permission)) {
            String[] permissions = permission.getGroupType().split(",");
            if (Arrays.asList(permissions).contains(e3.getKey())) {
                p3.setPermission(true);
            }
        }
    }

    @Override
    public JzPermission detail(String id) {
        JzPermission jzPermission = permissionMapper.selectById(id);
        return jzPermission;
    }

    @Override
    public Boolean update(JzPermission jzPermission) {
        Integer success = permissionMapper.updateById(jzPermission);
        return Optional.ofNullable(success).isPresent();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean save(PermissionSaveVO permissionSaveVO) {
        // 全部删除
        permissionMapper.delete(new EntityWrapper<JzPermission>().eq("user_id", permissionSaveVO.getUserId()));
        List<JzPermission> jzPermissionList = permissionSaveVO.getJzPermissionList();
        for (JzPermission jzPermission : jzPermissionList) {
            // 新增
            jzPermission.setCreateTime(LocalDateTime.now());
            jzPermission.setCreateId(ShiroUtils.getUserId());
            permissionMapper.insert(jzPermission);
        }
        return Boolean.TRUE;
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public Boolean batchSave(List<JzPermission> jzPermissionList) {
//        // 新增全部权限
//        for (JzPermission jzPermission : jzPermissionList) {
//            Long allocationId = jzPermission.getAllocationId();
//            Wrapper<EventresourceAllocationsDO> wrapper = new EntityWrapper<EventresourceAllocationsDO>()
//                    .eq("allocation_id", allocationId);
//            List<EventresourceAllocationsDO> eventresourceAllocationsDOList = allocationsMapper.selectList(wrapper);
//
//            // 搜索菜单 组别
//            Map<Integer, List<EventresourceAllocationsDO>> typeMap = eventresourceAllocationsDOList.stream()
//                    .collect(Collectors.groupingBy(EventresourceAllocationsDO::getType));
//            List<PermissionResourceListVO> typeList = getTypeList(allocationId, typeMap, eventresourceModuleDO);
//
//            for (PermissionResourceListVO permissionResourceListVO : typeList) {
//                // 拼接权限
//                StringJoiner sj = new StringJoiner(",");
//                for (PermissionResourceListVO resourceListVO : permissionResourceListVO.getPermissionList()) {
//                    sj.add(resourceListVO.getGroupType().toString());
//                }
//
//                JzPermission permission = new JzPermission();
//                permission.setAllocationId(allocationId);
//                permission.setType(permissionResourceListVO.getType());
//                permission.setGroupType(sj.toString());
//                permission.setUserId(permission.getUserId());
//                this.save(Arrays.asList(permission));
//            }
//
//
//        }
//        return null;
//    }

    /**
     * 分菜单 组别
     *
     * @param allocationId
     * @param typeMap
     * @param eventresourceModuleDO
     * @return
     */
    private static List<PermissionResourceListVO> getTypeList(Long allocationId, Map<Integer,
            List<EventresourceAllocationsDO>> typeMap, EventresourceModuleDO eventresourceModuleDO) {

        List<PermissionResourceListVO> typeList = typeMap.entrySet().stream().map(e2 -> {
            List<EventresourceAllocationsDO> allocationsDOList = e2.getValue();
            Map<Integer, List<EventresourceAllocationsDO>> groupTypeMap = allocationsDOList.stream()
                    .collect(Collectors.groupingBy(EventresourceAllocationsDO::getGroupType));
            List<PermissionResourceListVO> groupList = groupTypeMap.entrySet().stream().map(e3 -> {
                PermissionResourceListVO p3 = new PermissionResourceListVO();
                p3.setGroupType(e3.getKey());
                p3.setType(e2.getKey());
                p3.setId(allocationId + "-" + e2.getKey() + "-" + e3.getKey());
                return p3;
            }).collect(Collectors.toList());

            PermissionResourceListVO p2 = new PermissionResourceListVO();
            p2.setId(allocationId + "-" + e2.getKey());
            p2.setEveMoName(eventresourceModuleDO.getName());
            p2.setType(e2.getKey());
            p2.setPermissionList(groupList);
            return p2;
        }).collect(Collectors.toList());
        return typeList;
    }

    @Override
    public Boolean delete(JzPermission jzPermission) {
        // 删除整个资源权限 菜单为空
        if (Objects.isNull(jzPermission.getType())) {
            Integer delete = permissionMapper.delete(new EntityWrapper<JzPermission>()
                    .eq("allocation_id", jzPermission.getAllocationId())
                    .eq("user_id", jzPermission.getUserId()));
            return Optional.ofNullable(delete).isPresent();
        }

        // 删除菜单权限 组别为空
        if (ObjectUtil.isEmpty(jzPermission.getGroupType())) {
            Integer delete = permissionMapper.delete(new EntityWrapper<JzPermission>()
                    .eq("allocation_id", jzPermission.getAllocationId())
                    .eq("type", jzPermission.getType())
                    .eq("user_id", jzPermission.getUserId()));
            return Optional.ofNullable(delete).isPresent();
        }

        // 修改组别权限
        return deleteGroupPermission(jzPermission);
    }

    /**
     * 删除组别权限
     *
     * @param jzPermission
     * @return
     */
    private Boolean deleteGroupPermission(JzPermission jzPermission) {
        JzPermission permission = new JzPermission();
        permission.setAllocationId(jzPermission.getAllocationId());
        permission.setType(jzPermission.getType());
        JzPermission existPermission = permissionMapper.selectOne(permission);
        String groupType = jzPermission.getGroupType();
        String existGroupType = existPermission.getGroupType();
        //组别
        if (Objects.equals(existGroupType, groupType)) {
            Integer delete = permissionMapper.delete(new EntityWrapper<JzPermission>()
                    .eq("allocation_id", jzPermission.getAllocationId())
                    .eq("type", jzPermission.getType())
                    .eq("user_id", jzPermission.getUserId()));
            return Optional.ofNullable(delete).isPresent();
        }
        // 组别不同 替换
        String replace = existGroupType.replace(groupType + ",", "")
                .replace("," + groupType, "")
                .replace(groupType, "");
        existPermission.setGroupType(replace);
        Integer update = permissionMapper.updateById(existPermission);
        return Optional.ofNullable(update).isPresent();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDelete(List<JzPermission> jzPermissionList) {
        for (JzPermission jzPermission : jzPermissionList) {
            permissionMapper.delete(new EntityWrapper<JzPermission>()
                    .eq("allocation_id", jzPermission.getAllocationId())
                    .eq("user_id", jzPermission.getUserId()));
        }
        return Boolean.TRUE;
    }
}
